Skip to content

Conversation

Jack251970
Copy link
Member

CHANGES

If we click Clean cache button, it will throw DirectoryNotFoundException in pluginCacheDirectory.EnumerateDirectories. We should check if pluginCacheDirectory exists before calling EnumerateDirectories function.

TEST

Click Clean cache button twice.

@prlabeler prlabeler bot added the bug Something isn't working label Sep 18, 2025
@Jack251970 Jack251970 requested a review from Copilot September 18, 2025 11:16
@github-actions github-actions bot added this to the 2.1.0 milestone Sep 18, 2025
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR fixes a DirectoryNotFoundException that occurs when attempting to clean the cache twice by adding a check to verify the plugin cache directory exists before attempting to enumerate and delete its contents.

  • Adds existence check for plugin cache directory before enumeration
  • Refactors variable usage to reuse existing pluginCacheDirectory reference
  • Wraps cache deletion logic in conditional block to prevent exception

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link

gitstream-cm bot commented Sep 18, 2025

🥷 Code experts: Yusyuriv, onesounds

Jack251970, onesounds have most 👩‍💻 activity in the files.
Jack251970, Yusyuriv have most 🧠 knowledge in the files.

See details

Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs

Activity based on git-commit:

Jack251970 onesounds
SEP
AUG
JUL
JUN 7 additions & 0 deletions
MAY
APR 186 additions & 85 deletions 49 additions & 0 deletions

Knowledge based on git-blame:
Jack251970: 57%
Yusyuriv: 35%

✨ Comment /gs review for LinearB AI review. Learn how to automate it here.

Copy link

gitstream-cm bot commented Sep 18, 2025

Be a legend 🏆 by adding a before and after screenshot of the changes you made, especially if they are around UI/UX.

@Jack251970 Jack251970 requested a review from Copilot September 18, 2025 11:18
@Jack251970
Copy link
Member Author

@coderabbitai full review

Copy link
Contributor

coderabbitai bot commented Sep 18, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds an existence guard to ClearCacheFolder in SettingsPaneAboutViewModel to skip deletion when the plugin cache directory is missing, retains per-subdirectory deletion with logging, deletes the cache directory when present, and always raises CacheFolderSize property change to refresh UI.

Changes

Cohort / File(s) Summary
Settings about pane cache cleanup
Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs
Wrapped plugin cache deletion in an if (pluginCacheDirectory.Exists) guard; retained subdirectory deletion with try/catch and logging; deleted the cache directory via the existing pluginCacheDirectory; ensured OnPropertyChanged(nameof(CacheFolderSize)) is raised regardless of directory presence; no public API changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant VM as SettingsPaneAboutViewModel
  participant FS as FileSystem

  User->>VM: ClearCacheFolder()
  VM->>FS: Check pluginCacheDirectory.Exists
  alt Directory exists
    VM->>FS: Enumerate subdirectories
    loop For each subdirectory
      VM->>FS: Delete subdirectory (try/catch + log)
    end
    VM->>FS: Delete pluginCacheDirectory (non-recursive, try/catch + log)
  else Directory missing
    Note over VM: Skip deletion steps
  end
  VM->>VM: OnPropertyChanged("CacheFolderSize")
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • onesounds

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The PR title "Fix DirectoryNotFoundException when deleting cache twice" directly and concisely names the bug fixed and matches the change in ClearCacheFolder that adds an existence check before enumerating and deleting the plugin cache; it is specific, short, and useful for a teammate scanning history.
Description Check ✅ Passed The PR description describes the problem, the code change (checking pluginCacheDirectory.Exists before calling EnumerateDirectories), and includes a simple test case (click the Clean cache button twice), so it is directly related to the changeset and meets the lenient requirements for this check.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch clear_cache_twice

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

coderabbitai bot commented Sep 18, 2025

Caution

Review failed

The head commit changed during the review from 35a5e27 to ec182ad.

✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch clear_cache_twice

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.


Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link
Contributor

coderabbitai bot commented Sep 18, 2025

✅ Actions performed

Full review triggered.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs (1)

234-266: Good fix; add try/catch around enumeration to avoid TOCTOU crash.

Even with the Exists check, the directory can be removed between the check and EnumerateDirectories(), causing DirectoryNotFoundException (or UnauthorizedAccessException). Wrap the whole enumeration + final Delete in try/catch and log; also prefer FullName in logs.

-        // Check if plugin cache directory exists before attempting to delete
-        // Or it will throw DirectoryNotFoundException in `pluginCacheDirectory.EnumerateDirectories`
-        if (pluginCacheDirectory.Exists)
-        {
-            // Firstly, delete plugin cache directories
-            pluginCacheDirectory.EnumerateDirectories("*", SearchOption.TopDirectoryOnly)
-                .ToList()
-                .ForEach(dir =>
-                {
-                    try
-                    {
-                        // Plugin may create directories in its cache directory
-                        dir.Delete(recursive: true);
-                    }
-                    catch (Exception e)
-                    {
-                        App.API.LogException(ClassName, $"Failed to delete cache directory: {dir.Name}", e);
-                        success = false;
-                    }
-                });
-
-            // Then, delete plugin directory
-            var dir = pluginCacheDirectory;
-            try
-            {
-                dir.Delete(recursive: false);
-            }
-            catch (Exception e)
-            {
-                App.API.LogException(ClassName, $"Failed to delete cache directory: {dir.Name}", e);
-                success = false;
-            }
-        }
+        // Check if plugin cache directory exists before attempting to delete.
+        // Guard against TOCTOU by wrapping enumeration + delete.
+        try
+        {
+            if (pluginCacheDirectory.Exists)
+            {
+                // Firstly, delete plugin cache directories
+                pluginCacheDirectory.EnumerateDirectories("*", SearchOption.TopDirectoryOnly)
+                    .ToList()
+                    .ForEach(dir =>
+                    {
+                        try
+                        {
+                            // Plugin may create directories in its cache directory
+                            dir.Delete(recursive: true);
+                        }
+                        catch (Exception e)
+                        {
+                            App.API.LogException(ClassName, $"Failed to delete cache directory: {dir.FullName}", e);
+                            success = false;
+                        }
+                    });
+
+                // Then, delete plugin directory (should now be empty)
+                try
+                {
+                    pluginCacheDirectory.Delete(recursive: false);
+                }
+                catch (Exception e)
+                {
+                    App.API.LogException(ClassName, $"Failed to delete cache directory: {pluginCacheDirectory.FullName}", e);
+                    success = false;
+                }
+            }
+        }
+        catch (DirectoryNotFoundException)
+        {
+            // Swallow: directory disappeared between Exists check and enumeration.
+        }
+        catch (UnauthorizedAccessException e)
+        {
+            App.API.LogException(ClassName, $"Access denied enumerating plugin cache directory: {pluginCacheDirectory.FullName}", e);
+            success = false;
+        }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 820304c and 4bea410.

📒 Files selected for processing (1)
  • Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: gitStream workflow automation
  • GitHub Check: gitStream.cm
  • GitHub Check: gitStream.cm
  • GitHub Check: gitStream.cm
  • GitHub Check: gitStream.cm
  • GitHub Check: gitStream.cm
  • GitHub Check: build
🔇 Additional comments (1)
Flow.Launcher/SettingPages/ViewModels/SettingsPaneAboutViewModel.cs (1)

268-269: Unconditional CacheFolderSize notification — LGTM.

Matches the discussion to keep the UI accurate even if the folder was manually removed.

@Jack251970 Jack251970 merged commit 9030bff into dev Sep 18, 2025
14 checks passed
@Jack251970 Jack251970 deleted the clear_cache_twice branch September 18, 2025 11:59
@jjw24 jjw24 modified the milestones: 2.1.0, 2.0.1 Sep 21, 2025
jjw24 pushed a commit that referenced this pull request Sep 21, 2025
Fix DirectoryNotFoundException when deleting cache twice
@jjw24 jjw24 mentioned this pull request Sep 21, 2025
TBM13 pushed a commit to TBM13/Flow.Launcher that referenced this pull request Sep 23, 2025
…twice

Fix DirectoryNotFoundException when deleting cache twice
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants